use std::{
    collections::VecDeque,
    fs::{self, DirBuilder},
    path::{Path, PathBuf},
};

use clap::Args;

#[derive(Args, Debug)]
#[clap(about="图片裁剪", long_about=None)]
pub(crate) struct Crop {
    #[clap(
        value_parser,
        default_value = "./input",
        help = "输入目录",
        display_order = 1
    )]
    pub input: String,
    #[clap(
        value_parser,
        default_value = "./output",
        help = "输出目录",
        display_order = 2
    )]
    pub output: String,
    #[clap(
        long,
        value_parser,
        default_value = "600",
        help = "裁剪图片宽度",
        display_order = 3
    )]
    pub width: u32,
    #[clap(
        long,
        value_parser,
        default_value = "400",
        help = "裁剪图片高度",
        display_order = 4
    )]
    pub height: u32,
    #[clap(
        short,
        long,
        value_parser,
        default_value = "0",
        help = "裁剪左",
        display_order = 5
    )]
    pub left: u32,
    #[clap(
        short,
        long,
        value_parser,
        default_value = "0",
        help = "裁剪上",
        display_order = 6
    )]
    pub top: u32,
}

pub(crate) fn crop(input: &str, output: &str, left: u32, top: u32, width: u32, height: u32) {
    let result = fs::create_dir_all(output);
    if result.is_err() {
        println!("create output dir error: {:?}", result);
        return;
    }

    let output_file = Path::new(output);
    let paths = fs::read_dir(input).unwrap();
    for path in paths {
        let f = path.unwrap();
        let fpath = f.path();
        let ext = match fpath.extension() {
            Some(p) => p.to_str().unwrap(),
            None => "",
        };
        let lcext = &ext.to_lowercase();
        if ext.len() == 0 || (lcext != "png" && lcext != "jpg") {
            continue;
        }
        let mut im = image::open(&fpath).unwrap();
        let newim = im.crop(left, top, width, height);
        let file_name = f.file_name();
        let output_file = output_file.join(file_name);
        println!("输出文件：{}", output_file.to_str().unwrap());
        newim.save(output_file).unwrap();
    }
}

#[derive(Args, Debug)]
#[clap(about = "九宫格切割")]
pub(crate) struct NinePalaceGrid {
    #[clap(value_parser, help = "输入文件", display_order = 1)]
    pub input: PathBuf,
    #[clap(
        value_parser,
        default_value = "./output",
        help = "输出目录",
        display_order = 2
    )]
    pub output: PathBuf,
}

pub(crate) fn nine_palace_grid_crop(input: &PathBuf, output: &PathBuf) {
    let mut im = image::open(input).unwrap();
    let w = im.width();
    let h = im.height();
    let child_w = w / 3;
    let child_h = h / 3;
    let mut child_size_iter = VecDeque::from(vec![
        (0, 0, child_w, child_h),
        (child_w, 0, child_w, child_h),
        (child_w * 2, 0, w - child_w, child_h),
        (0, child_h, child_w, child_h),
        (child_w, child_h, child_w, child_h),
        (child_w * 2, child_h, w - child_w, child_h),
        (0, child_h * 2, child_w, h - child_h),
        (child_w, child_h * 2, child_w, h - child_h),
        (child_w * 2, child_h * 2, w - child_w, h - child_h),
    ]);
    let (file_prefix, file_ext) = match input.file_name() {
        Some(p) => p.to_str().unwrap().rsplit_once(".").unwrap(),
        None => ("", ""),
    };
    let mut i = 1usize;

    while let Some((t, l, w, h)) = child_size_iter.pop_front() {
        let new_im = im.crop(t, l, w, h);
        let mut output_file = output.join(file_prefix);

        if !output_file.as_path().exists() {
            DirBuilder::new()
                .recursive(true)
                .create(output_file.clone())
                .unwrap();
        }
        output_file = output_file.join(format!("{}-{}.{}", file_prefix, i, file_ext));
        println!(
            "{} {} {} {} 输出文件：{}",
            t,
            l,
            w,
            h,
            output_file.to_str().unwrap()
        );
        new_im.save(output_file).unwrap();
        i += 1;
    }
}
